/*
 * @Author: restart 2425792130@qq.com
 * @Date: 2024-08-29 17:22:02
 * @LastEditors: restart 2425792130@qq.com
 * @LastEditTime: 2024-08-30 17:59:13
 * @FilePath: \react\config\webpack.dev.js
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */

const path = require("path");
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
// const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
const CopyPlugin = require("copy-webpack-plugin");
// 返回处理样式的loader函数
const getStyleLoaders = (pre) => {
    return [
        MiniCssExtractPlugin.loader,
         'css-loader',
         // 处理css兼容性问题
         // 配合package.json里的browserslist来指定兼容性
         // 注意：browserslist里的版本号要和package.json里的版本号一致
         {
             loader:'postcss-loader',
             options:{
                 postcssOptions:{
                     plugins:[
                         [
                             'postcss-preset-env',
                             // {
                             //     browsers:'last 2 versions'
                             // }
                         ]
                     ]
                 }
             }
         },
         pre,
    ].filter(Boolean)
}

module.exports = {
    entry:'./src/index.js',
    output:{
        path:path.resolve(__dirname,'../dist'),
        filename:'static/js/[name].[contenthash:10].js',
        chunkFilename:'static/js/[name].[contenthash:10].chunk.js',    // 动态导入的模块，利用chunk来命名
        assetModuleFilename:'static/media/[hash:10][ext][query]',
        clean:true
    },
    module:{
        rules:[
            // 处理css文件，图片，js
            {
                test:/\.css$/,
                use:getStyleLoaders()
            },
            {
                test:/\.less$/,
                use:getStyleLoaders('less-loader')
            },
            {
                test:/\.s[ac]ss$/,
                use:getStyleLoaders('sass-loader')
            },
            {
                test:/\.styl$/,
                use:getStyleLoaders('stylus-loader')

            },
            // 处理图片
            {
                test:/\.(png|jpe?g|gif|webp|svg)$/,
                type:'asset',
                parser:{
                    dataUrlCondition:{
                        maxSize:10 * 1024
                    }
                }
            },
            // 处理其他资源
            {
                test:/\.(woff2?|ttf|eot)$/,
                type:'asset/resource',
                // generator:{
                //     filename:'static/fonts/[hash:10][ext][query]'
                // }
            },
            // 处理js   eslint对代码进行检查，bable对代码进行转化
            {
                test:/\.jsx?$/,
                // exclude:/node_modules/,
                include:path.resolve(__dirname,'../src'),
                loader:'babel-loader',
                options:{
                    cacheDirectory:true,   // 开启缓存
                    cacheCompression:false,  // 缓存不进行压缩
                    // plugins:[
                    //     'react-refresh/babel'
                    // ]
                }

            }
        ]
    },
    // 处理html文件
    plugins:[
        new ESLintWebpackPlugin({
            context:path.resolve(__dirname,'../src'),   //  需要eslint检查的文件
            exclude:'node_modules',      // 不包含依赖文件
            cache:true,   // 开启缓存
            cacheLocation:path.resolve(__dirname,'../node_modules/.cache/.eslintcache'),
            // 自动修复eslint的错误
            fix:true

        }),
        new HtmlWebpackPlugin({
            template:path.resolve(__dirname,'../public/index.html')
        }),
        // new ReactRefreshWebpackPlugin(), //激活js的HMR
        new MiniCssExtractPlugin({
            filename:'static/css/[name].[contenthash:10].css',  // 提取css文件
            // 提取动态导入的css文件
            // 动态导入的模块，利用chunk来命名
            chunkFilename:'static/css/[name].[contenthash:10].chunk.css' 
        }),
        new CopyPlugin({
            patterns: [
              {
                from: path.resolve(__dirname, "../public"),
                to: path.resolve(__dirname, "../dist"),
                toType: "dir",
                noErrorOnMissing: true, // 不生成错误
                globOptions: {
                  // 忽略文件
                  ignore: ["**/index.html"],
                },
                info: {
                  // 跳过terser压缩js
                  minimized: true,
                },
              },
            ],
          }),

    ],
    mode:'production', // 开发模式
    devtool:'source-map',   // 开发环境下生成的sourcemap(调试模式)
    optimization:{
        splitChunks:{
            chunks:'all'  // 所有的模块都进行拆分(代码分割压缩)
        },
        runtimeChunk:{
            name: (entrypoint) => `runtime~${entrypoint.name}.js` // 单独打包runtime
        },
        minimizer:[
            // 压缩css
            new CssMinimizerPlugin(),
            // 压缩js
            new TerserPlugin(),
            //压缩图片
            new ImageMinimizerPlugin({
                minimizer: {
                  implementation: ImageMinimizerPlugin.imageminGenerate,
                  options: {
                    plugins: [
                      ["gifsicle", { interlaced: true }],
                      ["jpegtran", { progressive: true }],
                      ["optipng", { optimizationLevel: 5 }],
                      [
                        "svgo",
                        {
                          plugins: [
                            "preset-default",
                            "prefixIds",
                            {
                              name: "sortAttrs",
                              params: {
                                xmlnsOrder: "alphabetical",
                              },
                            },
                          ],
                        },
                      ],
                    ],
                  },
                },
              }),
        ]
    },
    // webpack解析模块加载选项
    resolve:{
        extensions:['.jsx','.js','.json'],  // 自动补全文件后缀
        alias:{
            '@':path.resolve(__dirname,'../src')
        }
    },
    // devServer:{
    //     host:'localhost',
    //     port:8080,
    //     open:true,
    //     hot:true, // 开启热更新
    //     historyApiFallback:true
    // }
}